package org.phalanx.server.social;

import java.util.ArrayList;
import java.util.Hashtable;

import org.phalanx.messenging.MessageSendable;
import org.phalanx.messenging.PhalanxChatMessage;
import org.phalanx.server.ServerCache.CacheManager;
import org.phalanx.server.user.PhalanxUser;
import org.phalanx.server.user.UserManager;

public class PhalanxChatRoomManager {
	private Hashtable<String,PhalanxChatRoom> chatListenerList;
	private CacheManager cacheMgr;
	
	public PhalanxChatRoomManager(CacheManager c){
		chatListenerList = new Hashtable<String,PhalanxChatRoom>();
		cacheMgr = c;
	}
	
	public boolean createChatRoom(String chatName){
		boolean isSuccess = false;
		if (!chatListenerList.containsKey(chatName)){
			PhalanxChatRoom newRoom = new PhalanxChatRoom(chatName);
			chatListenerList.put(chatName, newRoom);
			isSuccess = true;
		}
		return isSuccess;
	}
	
	public boolean addChatListener(Integer uid, String chatName){
		PhalanxUser u = (PhalanxUser)cacheMgr.getElement("UserCache", uid);
		boolean isSuccess = false;
		if (u != null && chatListenerList.containsKey(chatName)){
			PhalanxChatRoom openRoom = chatListenerList.get(chatName);
			openRoom.setUser(uid);
			
			notifyUserChange(uid, chatName, PhalanxChatMessage.USER_JOINED);
			sendUserFullUserList(uid, chatName);
			isSuccess = true;
		}
		
		return isSuccess;
	}
	
	public boolean chatRoomExists(String chatroom){
		return chatListenerList.containsKey(chatroom);
	}
	
	public boolean removeChatListener(Integer uid, String chatName){
		PhalanxUser u = (PhalanxUser)cacheMgr.getElement("UserCache", uid);
		boolean isSuccess = false;
		
		if (u != null && chatListenerList.containsKey(chatName)){
			PhalanxChatRoom openRoom = chatListenerList.get(chatName);
			openRoom.removeUser(uid);
			
			if (openRoom.getUserList().isEmpty()){removeChatRoom(chatName);}
			
			notifyUserChange(uid, chatName, PhalanxChatMessage.USER_LEFT);
			isSuccess = true;
		}
		
		return isSuccess;
	}
	
	public boolean removeChatRoom(String chatName){
		boolean isSuccess = false;
		if (!chatListenerList.containsKey(chatName)){
			chatListenerList.remove(chatName);
			isSuccess = true;
		}
		return isSuccess;
	}
	
	public void onIncomingChat(String sender, PhalanxChatMessage msg){
		UserManager uMgr = new UserManager(cacheMgr);
		
		PhalanxUser u = uMgr.getUserByName(sender);
		
		if (u != null){
			onIncomingChat(u.getId(), msg);
		}
	}
	
	private void notifyUserChange(Integer uid, String chatroom, String action){
		PhalanxUser u = (PhalanxUser)cacheMgr.getElement("UserCache", uid);
		PhalanxChatRoom chat = chatListenerList.get(chatroom);
		PhalanxChatMessage pMsg = new PhalanxChatMessage();
		pMsg.setChatRoom(chatroom);
		pMsg.setAsStatus();
		pMsg.setUserForStatusChange(u.getUserName());
		
		if (u != null && chat != null){
			if (action.equals(PhalanxChatMessage.USER_JOINED)){
				pMsg.setStatus(PhalanxChatMessage.USER_JOINED);
				ArrayList<Integer> chatList = chat.getUserList();
				
				for (int i = 0; i < chatList.size(); i++){
					MessageSendable session = (MessageSendable)cacheMgr.getElement("UserWebFeedCache", chatList.get(i));	
					session.sendMessage(pMsg);
				}
			}
			else if (action.equals(PhalanxChatMessage.USER_LEFT)){
				pMsg.setStatus(PhalanxChatMessage.USER_LEFT);
				ArrayList<Integer> chatList = chat.getUserList();
				
				for (int i = 0; i < chatList.size(); i++){
					MessageSendable session = (MessageSendable)cacheMgr.getElement("UserWebFeedCache", chatList.get(i));	
					session.sendMessage(pMsg);
				}
			}
		}
	}
	
	private void sendUserFullUserList(Integer uid, String chatroom){
		PhalanxUser u = (PhalanxUser)cacheMgr.getElement("UserCache", uid);
		PhalanxChatRoom chat = chatListenerList.get(chatroom);
		PhalanxChatMessage pMsg = new PhalanxChatMessage();
		pMsg.setAsStatus();
		pMsg.setStatus(PhalanxChatMessage.USER_LIST);
		pMsg.setChatRoom(chatroom);
		
		ArrayList<Integer> fullUserList = chat.getUserList();
		
		for (int i = 0; i < fullUserList.size(); i++){
			PhalanxUser temp = (PhalanxUser)cacheMgr.getElement("UserCache", fullUserList.get(i));
			if (temp != null){
				pMsg.setUserForStatusChange(temp.getUserName());
			}
		}
		
		MessageSendable session = (MessageSendable)cacheMgr.getElement("UserWebFeedCache", u.getId());	
		session.sendMessage(pMsg);
	}
	
	public void onIncomingChat(Integer sender, PhalanxChatMessage msg){
		PhalanxUser u = (PhalanxUser)cacheMgr.getElement("UserCache", sender);
		String chatroom = msg.getFromMessage("chatroom").toString();
		
		if (u != null && chatListenerList.containsKey(chatroom)){
			msg.setSender(u.getUserName());
			msg.setAsChatMsg();
			
			PhalanxChatRoom chatObject = chatListenerList.get(chatroom);
			
			if (chatObject.hasUser(u.getId())){
				sendMessagesToChatRecipients(chatListenerList.get(chatroom).getUserList(), msg);
			}
		}
	}
	
	private void sendMessagesToChatRecipients(ArrayList<Integer> users, PhalanxChatMessage msg){
		for (int i = 0; i < users.size(); i++){
			Integer uid = users.get(i);
			
			MessageSendable session = (MessageSendable)cacheMgr.getElement("UserWebFeedCache", uid);
			
			session.sendMessage(msg);
		}
	}
	
	public ArrayList<String> getUserListAsNames(String chatroom){
		ArrayList<String> users = new ArrayList<String>();
	
		if (chatListenerList.containsKey(chatroom)){
			PhalanxChatRoom chat = chatListenerList.get(chatroom);
			
			ArrayList<Integer> uidList = chat.getUserList();
			
			for (int i = 0; i < uidList.size(); i++){
				Integer uid = uidList.get(i);
				
				PhalanxUser u = (PhalanxUser)cacheMgr.getElement("UserCache", uid);
				
				if (u != null){
					users.add(u.getUserName());
				}
			}
		}
		
		return users;
	}
}
